package com.iotimc.networklibrary.core;

import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import com.iotimc.networklibrary.entity.DownInfo;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import io.reactivex.functions.Function;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;
import retrofit2.Response;

/**
 * Created by david on 2017/10/11.
 *
 * @author david
 */

public class DownLoadFunction implements Function<Response<ResponseBody>, DownInfo> {
    private static final String TAG = "DownLoadFunction";
    DownInfo downInfo;

    public DownLoadFunction(DownInfo info) {
        this.downInfo = info;
    }

    public DownInfo write(Response<ResponseBody> response, String filename) {
        ResponseBody body = response.body();
        try {
            File root = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/document");
            File downFile = new File(root, filename);
            if (!root.exists()) {
                root.mkdirs();
            }
            if (downFile.exists()) {
                downFile.delete();
            }
            BufferedSink sink = Okio.buffer(Okio.sink(downFile));
            Buffer buffer = sink.buffer();
            int bufferSize = 200 * 1024;
            BufferedSource source = body.source();
            while (source.read(buffer, bufferSize) != -1) {
                sink.emit();
            }

            source.close();
            sink.close();
            String md5 = fileToMD5(downFile.getPath());

            downInfo.setFile(downFile);
            downInfo.setLocalMd5(md5);
            String disposition =  response.headers().get("Content-Disposition");
            if (!TextUtils.isEmpty(disposition)){
                if (disposition.split(";").length>2) {
                    String serverMd5 = disposition.
                            split(";")[2].replace("MD5File=", "");
                    Log.i(TAG, "serverMd5 = " + serverMd5);
                    downInfo.setServerMd5(serverMd5);
                }
            }

            return downInfo;
        } catch (Exception e) {
            e.printStackTrace();
        }


        return null;
    }

    @Override
    public DownInfo apply(Response response) throws Exception {
        return write(response, downInfo.getFileName());
    }

    /**
     * 把文件转成md5字符串
     *
     * @param path
     * @return
     */
    public static String fileToMD5(String path) {
        DigestInputStream dis = null;
        try {
            FileInputStream fis = new FileInputStream(path);
            MessageDigest digest = MessageDigest.getInstance("MD5");
            dis = new DigestInputStream(fis, digest);
            byte[] buffer = new byte[1024 * 256];
            while (true) {
                if (!(dis.read(buffer) > 0)) {
                    break;
                }
            }
            digest = dis.getMessageDigest();
            dis.close();
            BigInteger bigInt = new BigInteger(1, digest.digest());
            return bigInt.toString(16);
        } catch (IOException | NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
}